<?php

/**
 * Library :: DAL (Data Access Layer) :: DataObject
 *
 * Warlock is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 *
 * @package    warlock
 * @author     David Cole <neophyte@sourcetutor.com>
 * @license    GNU/GPL v2
 */

class Observer extends Object
{
    /**
     * Event Callbacks
     *
     * An associate array holding all the callbak functions
     * for a given event.
     *
     * @var array
     * @access private
     */
    var $_Events = array();

    var $_Plugins = array();

    var $_Error;

    /**
     * Constructor
     *
     * @return Observer
     */
    function __construct()
    {
        // Add self to vault
        Vault::Add('Observer', &$this);

        $this->_Error = &Vault::Get('Debug_Error');
    }

    /**
     * Add Listener
     *
     * @param string    $event     Name of the event to be hooked
     * @param callback  $callback  PHP callback type
     *
     * @return void
     * @access public
     */
    function AddListener($event, $callback)
    {
        $this->_Events[strtolower($event)][] = $callback;
    }

    /**
     * Raise Event
     *
     * Iterates over all the callback functions of
     * the given event passing each one the specified
     * arguments.
     *
     * @param string  $event  Name of the event to be raised
     * @param array   $args   An array of arguments to pass to each callback function
     *
     * @return array
     * @access public
     */
    function RaiseEvent($event, $args = array())
    {
        $event   = strtolower($event);        
        $results = array();

        if (isset($this->_Events[$event]))
        {
            $this->_Error->Log('Observer :: Raise Event \''.$event.'\', '.count($this->_Events[$event]).' Listeners', W_LOG_DEBUG);            
            
            for ($i = 0, $max = count($this->_Events[$event]); $i < $max; $i++)
                $results[] = call_user_func_array($this->_Events[$event][$i], $args);

            return $results;
        }
        else
            return array();
    }

    function LoadPlugin($application, $extension)
    {
        if (!isset($this->_Plugins[$application][$extension]))
        {
            using('Extensions.'.$application.'.'.$extension.'.plugin');

            if (class_exists(($class = 'Plugin_'.$application.'_'.$extension)))
            {
                $this->_Error->Log('Observer :: Loading Plugin \''.$class.'\'', W_LOG_DEBUG);
                $this->_Plugins[$application][$extension] = new $class();
            }
            else
            {

                $trace = debug_backtrace();
                $this->_Error->Log('Observer :: Error Loading \''.$class.'\' requested by \''.str_replace(W_ENV_PATH, '', $trace[0]['file']).':'.$trace[0]['line'].'\'', W_LOG_CRIT);
            }
        }
    }

    function LoadApplicationPlugins($application)
    {
        if (is_dir($dir = (W_ENV_PATH.'/Extensions/'.$application)))
        {
            $dh = opendir($dir);

            while (($file = readdir($dh)) !== false)
            {
                if ($file != '.' && $file != '..' && file_exists(W_ENV_PATH.'/Extensions/'.$application.'/'.$file.'/plugin.php'))
                {
                    using('Extensions.'.$application.'.'.$file.'.plugin');

                    if (class_exists(($class = 'Plugin_'.$application.'_'.$file)))
                    {
                        $this->_Error->Log('Observer :: Loading Plugin \''.$class.'\'', W_LOG_DEBUG);
                        $this->_Plugins = new $class();
                    }
                    else
                    {
                        $trace = debug_backtrace();
                        $this->_Error->Log('Observer :: Error Loading \''.$class.'\' requested by \''.str_replace(W_ENV_PATH, '', $trace[0]['file']).':'.$trace[0]['line'].'\'', W_LOG_CRIT);
                    }
                }
            }

            closedir($dh);
        }
    }
}

?>